﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionManagementStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
            try
            {
                Level3();
            }
            catch
            {
                Console.WriteLine("Main in catch");
            }

System.Reflection.MethodInfo
        }

        static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
        }

        static void Level3()
        {
            try
            {
                Console.WriteLine("Level3 in try");
                Level2();
            }
            catch
            {
                Console.WriteLine("Level3 in catch");
                throw;
            }
            finally
            {
                Console.WriteLine("Level3 in finally");
            }
        }

        static void Level2()
        {
            try
            {
                Console.WriteLine("Level2 in try");
                Level1();
            }
            catch
            {
                Console.WriteLine("Level2 in catch");
                throw;
            }
            finally
            {
                Console.WriteLine("Level2 in finally");
            }
        }

        static void Level1()
        {
            try
            {
                Console.WriteLine("Level1 in try");
                throw new Exception("Level1");
            }
            catch
            {
                Console.WriteLine("Level1 in catch");
                throw;
            }
            finally
            {
                Console.WriteLine("Level1 in finally");
            }
        }
    }

    interface IRepository<TEntity>
    {
        void Update(TEntity entity);
    }

    class ConcurrentException : Exception
    {
    }

    class EntityFrameworkRepository<TEntity> : IRepository<TEntity>
    {
        public void Update(TEntity entity)
        {
            try
            {
            }
            catch (EntityFrameworkConcurrentException ex)
            {
                throw new ConcurrentException(ex);
            }
        }
    }

    class NHibernateRepository<TEntity> : IRepository<TEntity>
    {
        public void Update(TEntity entity)
        {
            try
            {
            }
            catch (NHibernateConcurrentException ex)
            {
                throw new ConcurrentException(ex);
            }
        }
    }
}
